<?php
	class CMS_Xsl_DefinitionsParser extends XMLWriter  {
		
		function __construct($xml, $xsl){
			$this->xml = $xml;
			$this->xsl = $xsl;
			$this->xslDocument = null;
			$this->doc = new DOMDocument;
			$this->doc->load($this->xml);
			$this->time = time();
			$this->start();
			

			// global $dbh;
			// $sql = "INSERT INTO `__cms__`.`site_setup` (`key` , `value`) VALUES ('definitionsStructures', '".$this."');";
			// $sql = "UPDATE `__cms__`.`site_setup` SET `value` =  '".$this."' WHERE `site_setup`.`key` = 'definitionsStructures' LIMIT 1 ;";
			// print $sql;
			// $req  = $dbh->query($sql);
			// $res =  $req->fetchAll();
			// $sql = "UPDATE `__cms__`.`site_setup` SET `value` =  '".$this->time."' WHERE `site_setup`.`key` = 'definitionsDate' LIMIT 1 ;";
			// $req  = $dbh->query($sql);
		}
		
		function __toString(){
			return serialize($this->dataModel);
		}
		
		
		function parse (){
			
			
		
			$this->processChoices($this->doc->getElementsByTagName("choice"));
			$this->processRadios($this->doc->getElementsByTagName("radio"));
			$this->processSelects($this->doc->getElementsByTagName("select"));
			$this->processComposites($this->doc->getElementsByTagName("composite"));
			$this->processInputs($this->doc->getElementsByTagName("input"));
			$this->processTextareas($this->doc->getElementsByTagName("textarea"));
			$this->processElements($this->doc->getElementsByTagName("element"));
			$this->processFetchers($this->doc->getElementsByTagName("fetcher"));
			$this->processIncludes($this->doc->getElementsByTagName("include"));
			// $this->processChecks($this->doc->getElementsByTagName("check"));
			// $this->processFiles($this->doc->getElementsByTagName("file"));
			// $this->processHiddens($this->doc->getElementsByTagName("hidden"));
			
		}
		
		// user entry
		
		function processTextareas($textareas){
			foreach($textareas as $textarea){
				$this->processTextarea($textarea);
			}
		}
		
		function processTextarea($textarea){
			$tmpA  = array();
			$tmpA['type'] = 'textarea';
			
			$this->dataModel[$textarea->getAttribute('name')] = $tmpA;
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("match", $textarea->getAttribute('name'));
				$this->createVars($textarea);
				// p class="fline"
				$this->startElement("p");
				$this->writeAttribute("class", "fline");
					$this->startElement("label");
					$this->writeAttribute("for", "{"."$"."id}");
					$this->text($textarea->getAttribute('label'));
					$this->endElement();
					
					$this->startElement("textarea");
					$this->writeAttribute("id", "{"."$"."id}");
					$this->writeAttribute("name", "{"."$"."name}");
						$this->startElement("xsl:copy-of");
						$this->writeAttribute("disable-output-escaping", "yes");
						$this->writeAttribute("select", "child::node()");
						$this->endElement();
					$this->endElement();
					$this->startElement("xsl:if");
					$this->writeAttribute("test", "./@choice != ''");
							$this->callEditon($textarea);
					$this->endElement();
				$this->endElement();
			$this->endElement();
		}
		
		function processInputs($inputs){
			foreach($inputs as $input){
				$this->processInput($input);
			}
		}
		
		function processInput($input){
			$tmpA  = array();
			$tmpA['type'] = 'input';
			$tmpA['repeated'] = $input->getAttribute('repeated') || false;
			$tmpA['required'] = $input->getAttribute('required') || false;
			$this->dataModel[$input->getAttribute('name')] = $tmpA;
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("match", $input->getAttribute('name'));
				$this->createVars($input, false);
				//
				$this->startElement("p");
				$this->writeAttribute("class", "fline");
					$this->startElement("label");
					$this->writeAttribute("for", "{"."$"."id}");
					$this->text($input->getAttribute('label'));
					$this->endElement();
					
					$this->startElement("input");
					$this->writeAttribute("type", "text");
					$this->writeAttribute("id", "{"."$"."id}");
					$this->writeAttribute("name", "{"."$"."name}");
						$this->startElement("xsl:attribute");
						$this->writeAttribute("name", "value");
							$this->startElement("xsl:value-of");
							$this->writeAttribute("select", ".");
							$this->endElement();
						$this->endElement();
					$this->endElement();
					
					
					$this->startElement("xsl:if");
					$this->writeAttribute("test", "./@choice != ''");
							$this->callEditon($input);
					$this->endElement();
					
					
				$this->endElement();
			$this->endElement();
		}
		
		// cms componants
		
		function processComposites($composites){
			foreach($composites as $composite){
				$this->processComposite($composite);
			}
		}
		
		function processComposite($composite){
			
			$tmpA  = array();
			$tmpA['type'] = 'composite';
			$tmpA['repeated'] = $composite->getAttribute('repeated') or false;
			$tmpA['required'] = $composite->getAttribute('required') or false;
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("match", $composite->getAttribute('name'));
				$this->createVars($composite);

				$this->startElement("fieldset");
				$this->writeAttribute("class", "zone_composite blockToggle");
				$this->writeAttribute("id", "{"."$"."id}");
					
					$this->startElement("legend");
					$this->writeAttribute("class", "zone_title");
					$this->text($composite->getAttribute('label'));
						//<a href="#" class="toggleHandler fieldsetClose">Ouvrir/Fermer</a>
						$this->startElement("a");
						$this->writeAttribute("class", "toggleHandler toggleClose");
						$this->writeAttribute("href", "#");
						$this->text("Ouvrir/Fermer");
						$this->endElement();
						$this->callEditon($composite, 'true');
					$this->endElement();
					$this->startElement("div");
					$this->writeAttribute("class", "toggleCtn toggleClose");
					//
					
						// prise en charge des attributs
						foreach($composite->getElementsByTagName("item") as $item){
							$tag = $this->getTypeByName($item->getAttribute("name"));
							
							if($tag == "select" || $tag == "radio"){
								$tmpA["attribute"][] = $item->getAttribute("name");
								$this->startElement("xsl:call-template");
								$this->writeAttribute("name", $item->getAttribute("name"));
									$this->startElement("xsl:with-param");
									$this->writeAttribute("name", "id");
										$this->startElement("xsl:value-of");
										$this->writeAttribute("select", "./@uid");
										$this->endElement();
									$this->endElement();
									$this->startElement("xsl:with-param");
									$this->writeAttribute("name", "value");
									$this->writeAttribute("select", "./@".$item->getAttribute("name"));
									$this->endElement();
									
								$this->endElement();
								
							}
							else {
								$tmpA["node"][] = $item->getAttribute("name");
								
							}
							
						}
						
						$this->startElement("xsl:apply-templates");
						$this->writeAttribute("select", "child::node()");
							
							$this->startElement("xsl:with-param");
							$this->writeAttribute("name", "parentXPath");
							$this->writeAttribute("select", "$"."fullxpath");
							$this->endElement();
						$this->endElement();
					$this->endElement();
					
				$this->endElement();
			$this->endElement();
			
			
			$this->dataModel[$composite->getAttribute('name')] = $tmpA;
		}
		
		function processChoices($choices){
			foreach($choices as $choice){
				$this->processChoice($choice);
			}
		}
		
		function processChoice($choice){
			$tmpA  = array();
			$tmpA['type'] = 'choice';
			$tmpA['repeated'] = $choice->getAttribute('repeated') or false;
			$tmpA['required'] = $choice->getAttribute('required') or false;
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("match", $choice->getAttribute('name'));
				$this->createVars($choice, true);
				//
				
				$this->startElement("xsl:choose");
					$this->startElement("xsl:when");
					$this->writeAttribute("test", "count(node()) = 0");
						$this->startElement("fieldset");
						$this->writeAttribute("class", "zone_choice");
						$this->writeAttribute("id", $choice->getAttribute('name')."_{"."$"."uid}");
							$this->startElement("legend");
							$this->text($choice->getAttribute("label"));
							$this->endElement();
							$this->startElement("select");
							$this->writeAttribute("name", "choice_{"."$"."uid}");
								foreach($choice->getElementsByTagName("item") as $item){
									$tmpA["node"][] = $item->getAttribute("name");
									$this->startElement("option");
									$this->writeAttribute("value", $item->getAttribute("name"));
									$this->text($this->getLabelByName($item->getAttribute("name")));
									$this->endElement();
								}
							$this->endElement();
							//
							$this->startElement("input");
							$this->writeAttribute("type", "image");
							$this->writeAttribute("name", "CMS_Action");
							$this->writeAttribute("alt", "Choisir");
							$this->writeAttribute("src", "/css/skin/pictos/accept.png");
							$this->writeAttribute("value", "choice?choice_{"."$"."uid}?{"."$"."fullxpath}");
							$this->endElement();
						$this->endElement();
					$this->endElement();
					$this->startElement("xsl:otherwise");
						$this->startElement("xsl:apply-templates");
						$this->writeAttribute("select", "child::node()");
							
							$this->startElement("xsl:with-param");
							$this->writeAttribute("name", "parentXPath");
							$this->writeAttribute("select", "$"."fullxpath");
							$this->endElement();
						$this->endElement();
					$this->endElement();
				$this->endElement();
					
					
					
					//
			$this->endElement();
			
			$this->dataModel[$choice->getAttribute('name')] = $tmpA;
		}
		
		function processElements($elements){
			foreach($elements as $element){
				$this->processElement($element);
			}
		}
		
		function processElement($element){
			$tmpA  = array();
			$tmpA['type'] = 'element';
			$this->dataModel[$element->getAttribute('name')] = $tmpA;
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("match", $element->getAttribute('name'));
				//
				$this->startElement("xsl:copy-of");
				$this->writeAttribute("select", "child::node()");
				$this->endElement();
			$this->endElement();
		}
		
		function processFetchers($fetchers){
			foreach($fetchers as $fetcher){
				$this->processFetcher($fetcher);
			}
		}
		
		function processFetcher($fetcher){
			$tmpA  = array();
			$tmpA['type'] = 'fetcher';
			$this->dataModel[$fetcher->getAttribute('name')] = $tmpA;
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("match", $fetcher->getAttribute('name'));
				//
				/*
					<xsl:value-of select="php:function('getDateFormat', $dte_pub)" disable-output-escaping="yes"/>
				*/
				$this->createVars($fetcher);
				Zend_Debug::dump($fetcher->tagName);
				$str_args = "";
				foreach($fetcher->getElementsByTagName('fetcher-param') as $param){
					$str_args .= "string('" . $param->getAttribute("value") . "'), ";
				}
				$str_args = substr($str_args, 0, strlen($str_args) - 2);
				
				$this->startElement("xsl:value-of");
				$this->writeAttribute("select", "php:function('".$fetcher->getAttribute('name')."', $str_args)");
				$this->writeAttribute("disable-output-escaping", "yes");
				$this->endElement();
			$this->endElement();
		}
		

		// user choice
		
		function processRadios($radios){
			foreach($radios as $radio){
				$this->processRadio($radio);
			}
		}
		
		function processRadio($radio){
			$tmpA  = array();
			$tmpA['type'] = 'radio';
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("name", $radio->getAttribute('name'));
				//xsl:param
				$this->text("\n");
				$this->startElement("xsl:param");
				$this->writeAttribute("name", "value");
				$this->endElement();
				
				$this->createVars($radio);
				
				// p class="fline"
				$this->startElement("p");
				$this->writeAttribute("class", "fline");
					$this->startElement("label");
					$this->text($radio->getAttribute('label'));
					$this->endElement();
					
						$items = $radio->getElementsByTagName('item');
						foreach($items as $item){
							$this->startElement("label");
								$this->startElement("input");
								$this->writeAttribute("type", "radio");
								$this->writeAttribute("name", "{"."$"."name}");
								$this->writeAttribute("id", "{"."$"."id}");
								$this->writeAttribute("value", $item->getAttribute("value"));
									$this->startElement("xsl:if");
									$this->writeAttribute("test", "$"."value = '".$item->getAttribute("value")."'");
										$this->startElement("xsl:attribute");
										$this->writeAttribute("name", "checked");
										$this->text('checked');
										$this->endElement();
									$this->endElement();
								$this->endElement();
								$this->text($item->getAttribute("label"));
							$this->endElement();
						}
					$this->endElement();
					
				$this->endElement();
				
				$this->dataModel[$radio->getAttribute('name')] = $tmpA;

		}
		
		function processSelects($selects){
			foreach($selects as $select){
				$this->processSelect($select);
			}
		}
		
		function processSelect($select){
			$tmpA  = array();
			$tmpA['type'] = 'select';
			$this->dataModel[$select->getAttribute('name')] = $tmpA;
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("name", $select->getAttribute('name'));
				
				$this->text("\n");
				//xsl:param
				$this->startElement("xsl:param");
				$this->writeAttribute("name", "value");
				$this->endElement();
				$this->text("\n");
				
				$this->createVars($select);
				
				// p class="fline"
				$this->startElement("p");
				$this->writeAttribute("class", "fline");
					$this->startElement("label");
					$this->writeAttribute("for", "{"."$"."id}");
					$this->text($select->getAttribute('label'));
					$this->endElement();
					
					$this->startElement("select");
					$this->writeAttribute("id", "{"."$"."id}");
					$this->writeAttribute("name", "{"."$"."name}");
					
					$opts = $select->getElementsByTagName('option');
					foreach($opts as $opt){
						$this->startElement("option");
						$this->writeAttribute("value", $opt->getAttribute('value'));
							$this->startElement("xsl:if");
							$this->writeAttribute("test", "$"."value = '".$opt->getAttribute('value')."'");
								$this->startElement("xsl:attribute");
								$this->writeAttribute("name", "selected");
								$this->text('selected');
								$this->endElement();
							$this->endElement();
							$this->text($opt->getAttribute('label'));
						$this->endElement();
					}
					$this->endElement();
				$this->endElement();
			$this->endElement();
		}
		
		// specific action
		
		
		
		function processIncludes($includes){
			foreach($includes as $include){
				$this->processInclude($include);
			}
		}
		
		function processInclude($include){
			$tmpA  = array();
			$tmpA['type'] = 'include';
			$this->dataModel[$include->getAttribute('name')] = $tmpA;
			
			$this->text("\n");
			// xsl:template name
			$this->startElement("xsl:template");
			$this->writeAttribute("match", $include->getAttribute('name'));
				//
				/*
					<xsl:text disable-output-escaping="yes">&lt;?php $xmlURL="</xsl:text>
					<xsl:value-of select="$xml" />
					<xsl:text disable-output-escaping="yes">";include("editor.php");?></xsl:text>
				*/
				
				
				$this->startElement("xsl:text");
				$this->writeAttribute("disable-output-escaping", "no");
				$this->text("include(ROOTPATH.\'".$include->getAttribute('url')."\');");
				$this->endElement();
			$this->endElement();
		}
		
		/* Internal functions */
		
		function start(){
			// start
			$this->openMemory();
			$this->setIndent(true);
			$this->setIndentString("	");
			$this->startDocument('1.0', 'UTF-8');
			
			
			// xsl:stylesheet
			$this->startElement("xsl:stylesheet");
			
			$this->writeAttribute("version", "1.1");
			$this->writeAttribute("xmlns:xsl", "http://www.w3.org/1999/XSL/Transform"); 
			$this->writeAttribute("xmlns:php", "http://php.net/xsl");
			$this->writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
				
				// xsl:import
				$this->startElement("xsl:import");
				$this->writeAttribute("href", "functions.xsl");
				$this->endElement();
				
				// xsl:output
				$this->startElement("xsl:output");
				$this->writeAttribute("method", "html");
				$this->writeAttribute("version", "1.0");
				$this->writeAttribute("encoding", "utf-8");
				$this->writeAttribute("omit-xml-declaration", "yes");
				$this->writeAttribute("indent", "yes");
				$this->endElement();
				
				// 
				// xsl:strip-space
				$this->startElement("xsl:strip-space");
				$this->writeAttribute("elements", "*");
				$this->endElement();

			
			$this->parse();
			
			// /xsl:stylesheet
			$this->endElement();
			// close documentElement
			$this->endDocument();
			
			
			$this->xslDocument = $this->outputMemory(); 
			
			// create file
			$file = fopen($this->xsl, "w");
			if(!$file) die($this->xsl.' is not accessible.');
			else fwrite($file, $this->xslDocument);
			
			
			//$_SESSION['messager']->write('onDefinitionsInit');
		}
		
		function getLabelByName($name){
			$dom = $this->doc->getElementsByTagName("definitions")->item(0)->childNodes;
			$name = trim($name);
			foreach($dom as $el){
				if($el->nodeType == 1 && $el->getAttribute("name") == $name) {return  $el->getAttribute("label");}
			}
			return "UNKNOWN";
		}
		
		function isCompositeByName($name){
			$dom = $this->doc->getElementsByTagName("*");
			$name = trim($name);
			foreach($dom as $el){
				if(trim($el->getAttribute("name")) == $name && $el->tagName == "composite") { return true;}
				else if(trim($el->getAttribute("name")) == $name && $el->tagName != "composite") { return false;}
			}
			return false;
		}
		
		function getTypeByName($name){
			$dom = $this->doc->getElementsByTagName("definitions")->item(0)->childNodes;
			$name = trim($name);
			foreach($dom as $el){
				if($el->nodeType == 1 && $el->getAttribute("name") == $name) { return $el->tagName;}
			}
			return false;
		}
		
		function save(){
			global $dbh;
			$sql = "
				INSERT INTO `__cms__`.`page_uid` (
					`page_uid_id` ,
					`page_uid_xmlpath` ,
					`page_uid_htmlpath` ,
					`page_uid_fullpath` ,
					`page_uid_title` ,
					`page_uid_name` ,
					`page_uid_breadcrumb_name` ,
					`page_uid_version` ,
					`page_uid_active` ,
					`page_uid_date_create` ,
					`page_uid_date_create_by`
				)
				VALUES (
					'".$this->uid."', '".$this->xmlURL."', '".$this->fullpath."', '".$this->fullpath."', ".$dbh->quote($this->title).", ".$dbh->quote($this->name).", ".$dbh->quote($this->name).", '1', '0', CURRENT_TIMESTAMP,".$dbh->quote($this->user["nick"])." 
				);
			";
			print $sql;
			
			$req  = $dbh->query($sql);
			$res =  $req->fetchAll();
		}
		
		function createNode($nodeName){
			$this->startElement($nodeName);
			$data = $this->data[$nodeName];
			foreach($data as $k=>$v){
				$this->writeAttribute($v[0], $v[1]);
			}
			$this->endElement();
		}
		
		function createNodes(){
			foreach($this->data as $prop=>$val){
				if(is_array($val) && $prop != $this->root){
					$this->createNode($prop);
				}
			}
		}
		
		//transforme les S_POST en un tableau indexe
		function modelizeData ($var){
			$vars = array();
			
			foreach($var as $k=>$v){
				$str = split("_", $k);
				if(isset($str[1])) {
					if(@$vars[$str[0]]){
						array_push($vars[$str[0]], array($str[1], $v));
					}
					else {
						array_push($vars, $str[0]);
						$vars[$str[0]] = array(array($str[1], $v));
					}
				}
			}
			//printA($vars);
			return $vars;
		}
		
		function createVars($n, $isChoice = false){
			
			$this->text("\n");
			// 
			$this->startElement("xsl:param");
			$this->writeAttribute("name", "parentXPath");
			$this->endElement();
			// 
			$this->startElement("xsl:variable");
			$this->writeAttribute("name", "label");
			$this->text($n->getAttribute('label'));
			$this->endElement();
			//
			if($isChoice){
				$this->startElement("xsl:variable");
				$this->writeAttribute("name", "uid");
				$this->writeAttribute("select", "generate-id()");
				$this->endElement();

			}
			else {
				$this->startElement("xsl:variable");
				$this->writeAttribute("name", "uid");
				$this->writeAttribute("select", "./@uid");
				$this->endElement();
			}
			// 
			$this->startElement("xsl:variable");
			$this->writeAttribute("name", "xpath");
			$this->writeAttribute("select", "./@xpath");
			$this->endElement();				
			// 
			$this->startElement("xsl:variable");
			$this->writeAttribute("name", "fullxpath");
			$this->writeAttribute("select", "concat("."$"."parentXPath,'/' ,$"."xpath)");
			$this->endElement();				
			// 
			$this->startElement("xsl:variable");
			$this->writeAttribute("name", "name");
			$this->writeAttribute("select", "concat('".$n->getAttribute('name')."', '_',"."$"."uid)");
			$this->endElement();				
			// 
			$this->startElement("xsl:variable");
			$this->writeAttribute("name", "id");
			$this->writeAttribute("select", "concat('nd_',"."$"."uid)");
			$this->endElement();				
			//
			$this->startElement("xsl:variable");
			$this->writeAttribute("name", "alone");
				$this->startElement("xsl:value-of");
				$this->writeAttribute("select", "count(parent::*/".$n->getAttribute('name').")");
				$this->endElement();
			$this->endElement();
			$this->text("\n");
		}
		
		function callEditon($n, $full = 'false'){
			$this->startElement("xsl:call-template");
			$this->writeAttribute("name", "edition");
				//
				$this->startElement("xsl:with-param");
				$this->writeAttribute("name", "xpath");
					$this->startElement("xsl:value-of");
					$this->writeAttribute("select", "$"."fullxpath");
					$this->endElement();
				$this->endElement();
				//
				$this->startElement("xsl:with-param");
				$this->writeAttribute("name", "name");
				$this->writeAttribute("select", "name()");
				$this->endElement();
				//
				$this->startElement("xsl:with-param");
				$this->writeAttribute("name", "repeated");
				$this->text($n->getAttribute("repeated"));
				$this->endElement();
				//
				$this->startElement("xsl:with-param");
				$this->writeAttribute("name", "id");
				$this->writeAttribute("select", "$"."uid");
				$this->endElement();
				//
				$this->startElement("xsl:with-param");
				$this->writeAttribute("name", "isAlone");
				$this->writeAttribute("select", "$"."alone");
				$this->endElement();
				//
				$this->startElement("xsl:with-param");
				$this->writeAttribute("name", "isComposite");
				$this->writeAttribute("select", "'".$full."'");
				$this->endElement();
			$this->endElement();
		}
	}
?>
